#include <kernel.h>
#include <i386.h>

Bool valid_fd(int fd);


Bool valid_fd(int fd){
    return fd >= 0 && fd < FDTAB_SZ ? TRUE : FALSE;
}


extern int di_open(PCB* process, int devnum){
    
    if(!(devnum >= 0 && devnum < DEVTAB_SZ))
    return -1;

    if(devtab[devnum].dvowner != NULL)
    return -1;

    size_t i;
    for(i = 0; i < FDTAB_SZ; i++){
        if(process->fdtab[i].dev == NULL){
            process->fdtab[i].dev = &devtab[devnum];
            
            // set device's current owner
            devtab[devnum].dvowner = process;
            devtab[devnum].dveof = FALSE;
            
            (*devtab[devnum].dvopen)(&devtab[devnum]);
            
            return i;
        }
    }
    
    return -1;
}

extern int di_close(PCB* process, int fd){
    
    if(!valid_fd(fd))
    return -1;
    
    DEVICE* dev = process->fdtab[fd].dev; 
    
    if(!dev)
    return -1;
    
    (*dev->dvclose)(dev);
     
    process->fdtab[fd].dev->dvowner = NULL;
    process->fdtab[fd].dev = NULL;
    
    return 0;
}

extern int di_write(PCB* process, int fd, void* buf, int buflen){
    
    /*
    if(!valid_fd(fd))
    return -1;
    
    DEVICE* dev = process->fdtab[fd].dev;
    
    if(!dev)
    return -1;
     
    return (*dev->dvwrite))(dev, buf, buflen);
    */
    return -1;
}

extern int di_read(PCB* process, int fd, void* buf, int buflen){

    if(!valid_fd(fd)){
        //kprintf("di_read: invalid fd = %d\n", fd);    
        return -1;
    }
    
    DEVICE* dev = process->fdtab[fd].dev; 
    
    if(!dev){
        //kprintf("di_read: invalid device\n");       
        return -1;
    }
    
    return (*dev->dvread)(dev, buf, buflen);
  
}

extern int di_ioctl(PCB* process, int fd, int cmd){
    
    if(!valid_fd(fd))
    return -1;
     
    DEVICE* dev = process->fdtab[fd].dev; 
    
    if(!dev)
    return -1;
    
    return (*dev->dvcntl)(dev, cmd);

}
